<?php

defined('SYSPATH') or die('No direct script access.');

abstract class Ads {

	/**
	 * @var   string     default driver to use
	 */
	public static $default = 'cian';

	/**
	 * @var   Kohana_Cache instances
	 */
	public static $instances = array();
	protected $_data = '';
	protected $_typeid = '';

	/**
	 * Creates a singleton of a Kohana Ads group. If no group is supplied
	 * the __default__ cache group is used.
	 *
	 *     // Create an instance of the default group
	 *     $default_group = Ads::instance();
	 *
	 *     // Create an instance of a group
	 *     $foo_group = Ads::instance('cian');
	 *
	 *     // Access an instantiated group directly
	 *     $foo_group = Ads::$instances['default'];
	 *
	 * @param   string  $group  the name of the cache group to use [Optional]
	 * @return  Ads
	 * @throws  Ads_Exception
	 */
	public static function instance($group = NULL) {
		// If there is no group supplied
		if ($group === NULL) {
			// Use the default setting
			$group = Ads::$default;
		}

		if (isset(Ads::$instances[$group])) {
			// Return the current group if initiated already
			return Ads::$instances[$group];
		}

		$config = Kohana::$config->load('ads');

		if (!$config->offsetExists($group)) {
			throw new Ads_Exception(
			'Failed to load Ads group: :group', array(':group' => $group)
			);
		}

		$config = $config->get($group);

		// Create a new cache type instance
		$apartment_class = 'Ads_' . ucfirst($config['driver']);
		Ads::$instances[$group] = new $apartment_class($config);

		// Return the instance
		return Ads::$instances[$group];
	}

	/**
	 * @var  Config
	 */
	protected $_config = array();

	/**
	 * Ensures singleton pattern is observed, loads the default expiry
	 *
	 * @param  array  $config  configuration
	 */
	protected function __construct(array $config) {
		$this->config($config);
	}

	/**
	 * Getter and setter for the configuration. If no argument provided, the
	 * current configuration is returned. Otherwise the configuration is set
	 * to this class.
	 *
	 *     // Overwrite all configuration
	 *     $cache->config(array('driver' => 'memcache', '...'));
	 *
	 *     // Set a new configuration setting
	 *     $cache->config('servers', array(
	 *          'foo' => 'bar',
	 *          '...'
	 *          ));
	 *
	 *     // Get a configuration setting
	 *     $servers = $cache->config('servers);
	 *
	 * @param   mixed    key to set to array, either array or config path
	 * @param   mixed    value to associate with key
	 * @return  mixed
	 */
	public function config($key = NULL, $value = NULL) {
		if ($key === NULL)
			return $this->_config;

		if (is_array($key)) {
			$this->_config = $key;
		}
		else {
			if ($value === NULL)
				return Arr::get($this->_config, $key);

			$this->_config[$key] = $value;
		}

		return $this;
	}

	public function query($url, $cache = FALSE) {
		if (isset(Cache::$instances['redis'])) {
			$redis = Cache::$instances['redis'];
		}
		else {
			$redis = Cache::instance('redis');
		}
		$data = $redis->get('query:'.md5($url), FALSE);
		if (!empty($data) AND $cache == TRUE) {
			$this->_data = $data;
			return $this;
		}
		else {
			$url_parts = parse_url($url);
			parse_str($url_parts['query'], $get_array);
			$url = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'];
			$request = Request::factory($url)->query($get_array)
					->method(Request::GET);
			$request->client()
					->options(array(
						CURLOPT_SSL_VERIFYPEER => FALSE,
						CURLOPT_USERAGENT => empty(Request::$user_agent) ? Request::$user_agent : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36',
						CURLOPT_HTTPHEADER => array(
							'Accept-Encoding:gzip,deflate,sdch',
							'Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
						),
						CURLOPT_FOLLOWLOCATION => TRUE,
						CURLOPT_COOKIEFILE => APPPATH . "config/cookie.file",
						CURLOPT_COOKIEJAR => APPPATH . "config/cookie.file",
			));
			$response = $request->execute();
			$data = $response->body();
			$redis->set('query:'.md5($url), $data, 300);
		}
		$this->_data = $data;
		return $this;
	}

	abstract public function parse($url);

	abstract public function write($data);

	abstract public function read($adsid);

	abstract public function count();

	public function cleaning() {

	}

}
